package fei.typhoon.engine.math;

import android.graphics.Matrix;
import android.graphics.PointF;

public class FeiPolygon {

	private float[] vertexs = null;

	private float[] initial = null;

	public FeiPolygon() {
	}

	public FeiPolygon(float... vertexs) {
		set(vertexs);
	}

	public void set(float... vertexs) {
		this.vertexs = vertexs;
		if (vertexs != null && vertexs.length > 0) {
			initial = new float[vertexs.length];
			for (int i = 0; i < vertexs.length; i++) {
				initial[i] = vertexs[i];
			}
		}
	}

	public void reset() {
		if (initial != null && initial.length > 0) {
			vertexs = new float[initial.length];
			for (int i = 0; i < initial.length; i++) {
				vertexs[i] = initial[i];
			}
		}
	}

	public boolean pointInRegion(float x, float y) {

		int n, i, sum, t1, t2;
		byte ret = 0;
		float f;
		PointF[] ptbuf;

		n = vertexs.length / 2;
		ptbuf = new PointF[n + 1];
		for (int k = 0, j = 0; k < n; k++, j += 2) {
			ptbuf[k] = new PointF();
			ptbuf[k].x = vertexs[j];
			ptbuf[k].y = vertexs[j + 1];
		}
		// 把起始点放到最终点。
		ptbuf[n] = new PointF();
		ptbuf[n].x = ptbuf[0].x;
		ptbuf[n].y = ptbuf[0].y;
		// 坐标平移
		for (i = 0; i <= n; i++) {
			ptbuf[i].x -= x;
			ptbuf[i].y -= y;
		}
		// 计算象限
		t1 = ptbuf[0].x >= 0 ? (ptbuf[0].y >= 0 ? 0 : 3) : (ptbuf[0].y >= 0 ? 1
				: 2);
		for (sum = 0, i = 1; i <= n; i++) {
			if (ptbuf[i].x == 0 && ptbuf[i].y == 0) {
				// 被测点为多边形顶点。
				ret = 1;
				break;
			}
			f = ptbuf[i].y * ptbuf[i - 1].x - ptbuf[i].x * ptbuf[i - 1].y; // 计算叉积
			if (f == 0 && ptbuf[i - 1].x * ptbuf[i].x <= 0
					&& ptbuf[i - 1].y * ptbuf[i].y <= 0) {
				// 点在边上
				ret = 1;
				break;
			}
			// 计算象限
			t2 = ptbuf[i].x >= 0 ? (ptbuf[i].y >= 0 ? 0 : 3)
					: (ptbuf[i].y >= 0 ? 1 : 2);
			if (t2 == (t1 + 1) % 4)
				// 情况1
				sum += 1;
			else if (t2 == (t1 + 3) % 4)
				// 情况2
				sum -= 1;
			else if (t2 == (t1 + 2) % 4) {
				// 情况3
				if (f > 0)
					sum += 2;
				else
					sum -= 2;
			}
			t1 = t2;
		}

		if (i > n) {
			if (sum == 0) {
				// 点在多边形外
				ret = 0;
			} else if (sum == 1) {
				// 点在多边形的某条边上
				ret = 1;
			} else {
				// 点在多边形内
				ret = 2;
			}
		}

		return (ret != 0);
	}

	public float[] getVertexs() {
		return vertexs;
	}

	public void matrix(Matrix matrix) {
		int i = 0;
		while (i < vertexs.length) {
			vertexs[i] = 0;
			i++;
		}
		matrix.mapPoints(vertexs, initial);
	}

}
